import pandas as pd

from LogConfig import getLog

logger = getLog("BZ凭证处理")
from UTIL import log_with_company, format_date, get_days_diff





def process_bz_vouchers(公司代码, df, current_date):
    """
    处理BZ类型凭证

    参数:
        公司代码: 公司代码字符串
        df: 包含所有凭证数据的DataFrame
        current_date: 当前日期，用于计算天数差

    返回:
        write_data: 需要写入的数据列表
    """
    log_with_company(公司代码, "info", "开始处理BZ类型凭证")

    # 筛选凭证类型为"BZ"的记录
    df_filtered = df[df['凭证类型'] == 'BZ']
    log_with_company(公司代码, "info", f"BZ类型凭证共{len(df_filtered)}条")

    # 按"客商名称"列分组并计算本币金额总和，保留2位小数
    grouped = df_filtered.groupby('客商名称')['本币金额'].sum().round(2).reset_index()
    log_with_company(公司代码, "info", f"BZ类型凭证按客商分组后共{len(grouped)}组")

    write_data = []

    # 处理正数金额
    positive_amounts = grouped[grouped['本币金额'] > 0]
    log_with_company(公司代码, "info", f"BZ类型正数金额共{len(positive_amounts)}组")

    # for _, row in positive_amounts.iterrows():
    #     客商名称 = row['客商名称']
    #     original_records = df_filtered[df_filtered['客商名称'] == 客商名称]
    #
    #     # 遍历所有原始记录
    #     for _, record in original_records.iterrows():
    #         # 写入所有记录，并添加客商名称作为分组关键词
    #         write_data.append({
    #             '分组关键词': 客商名称,
    #             '凭证日期': format_date(record['凭证日期']),
    #             '凭证类型': record['凭证类型'],
    #             '凭证编号': record['凭证编号'],
    #             '客商名称': 客商名称,
    #             '本币金额': record['本币金额'],
    #             '文本': record['文本']
    #         })

    for _, row in positive_amounts.iterrows():
        客商名称 = row['客商名称']
        original_records = df_filtered[df_filtered['客商名称'] == 客商名称]

        # 按凭证日期降序排序，确保优先处理时间较晚的记录
        original_records = original_records.sort_values('凭证日期', ascending=True)

        # 分离正负金额记录
        positive_records = original_records[original_records['本币金额'] > 0]
        negative_records = original_records[original_records['本币金额'] < 0]

        # 用于记录已处理的记录
        processed_positive = set()
        processed_negative = set()

        # 处理正负金额抵消
        for pos_idx, pos_record in positive_records.iterrows():
            for neg_idx, neg_record in negative_records.iterrows():
                # 如果金额相等且都未被处理过，则进行抵消
                if (abs(pos_record['本币金额']) == abs(neg_record['本币金额'])
                        and pos_idx not in processed_positive
                        and neg_idx not in processed_negative):
                    processed_positive.add(pos_idx)
                    processed_negative.add(neg_idx)
                    log_with_company(公司代码, "info",
                                     f'√ BZ类型凭证「{pos_record["凭证编号"]}」和「{neg_record["凭证编号"]}」金额抵消，金额：{pos_record["本币金额"]:.2f}')
                    break

        # 输出未抵消的记录
        for idx, record in original_records.iterrows():
            if idx in processed_positive or idx in processed_negative:
                continue  # 跳过已抵消的记录

            # 对于负金额记录，检查是否超过90天
            if record['本币金额'] < 0:
                凭证日期 = format_date(record['凭证日期'])
                voucher_date = pd.to_datetime(record['凭证日期'])
                days_diff = get_days_diff(current_date, voucher_date)

                if days_diff > 90:
                    log_with_company(公司代码, "error",
                                     f'× BZ类型凭证「{record["凭证编号"]}」，按客商名称「{客商名称}」金额「{record["本币金额"]:.2f}」，凭证日期「{凭证日期}」距今超过3个月')
                    write_data.append({
                        '分组关键词': 客商名称,
                        '凭证日期': format_date(record['凭证日期']),
                        '凭证类型': record['凭证类型'],
                        '凭证编号': record['凭证编号'],
                        '客商名称': 客商名称,
                        '本币金额': record['本币金额'],
                        '文本': record['文本']
                    })
                else:
                    log_with_company(公司代码, "debug",
                                     f'√ BZ类型凭证「{record["凭证编号"]}」，按客商名称「{客商名称}」金额「{record["本币金额"]:.2f}」，凭证日期「{凭证日期}」距今不超过3个月')
                    write_data.append({
                        '分组关键词': 客商名称,
                        '凭证日期': format_date(record['凭证日期']),
                        '凭证类型': record['凭证类型'],
                        '凭证编号': record['凭证编号'],
                        '客商名称': 客商名称,
                        '本币金额': record['本币金额'],
                        '文本': record['文本']
                    })
            else:
                # 正金额记录直接写入
                write_data.append({
                    '分组关键词': 客商名称,
                    '凭证日期': format_date(record['凭证日期']),
                    '凭证类型': record['凭证类型'],
                    '凭证编号': record['凭证编号'],
                    '客商名称': 客商名称,
                    '本币金额': record['本币金额'],
                    '文本': record['文本']
                })

    # ————————

    # 处理负数金额
    negative_amounts = grouped[grouped['本币金额'] < 0]
    log_with_company(公司代码, "info", f"BZ类型负数金额共{len(negative_amounts)}组")

    for _, row in negative_amounts.iterrows():
        小计金额 = row['本币金额']
        客商名称 = row['客商名称']
        original_records = df_filtered[df_filtered['客商名称'] == 客商名称]

        # 按凭证日期降序排序，确保优先处理时间较晚的记录
        original_records = original_records.sort_values('凭证日期', ascending=True)

        # 分离正负金额记录
        positive_records = original_records[original_records['本币金额'] > 0]
        negative_records = original_records[original_records['本币金额'] < 0]

        # 用于记录已处理的记录
        processed_positive = set()
        processed_negative = set()

        # 处理正负金额抵消
        for pos_idx, pos_record in positive_records.iterrows():
            for neg_idx, neg_record in negative_records.iterrows():
                # 如果金额相等且都未被处理过，则进行抵消
                if (abs(pos_record['本币金额']) == abs(neg_record['本币金额'])
                        and pos_idx not in processed_positive
                        and neg_idx not in processed_negative):
                    processed_positive.add(pos_idx)
                    processed_negative.add(neg_idx)
                    log_with_company(公司代码, "info",
                                     f'√ BZ类型凭证「{pos_record["凭证编号"]}」和「{neg_record["凭证编号"]}」金额抵消，金额：{pos_record["本币金额"]:.2f}')
                    break

        # 输出未抵消的记录
        for idx, record in original_records.iterrows():
            if idx in processed_positive or idx in processed_negative:
                continue  # 跳过已抵消的记录

            凭证日期 = format_date(record['凭证日期'])
            voucher_date = pd.to_datetime(record['凭证日期'])
            days_diff = get_days_diff(current_date, voucher_date)

            if days_diff > 90:
                log_with_company(公司代码, "error",
                                 f'× BZ类型凭证「{record["凭证编号"]}」，按客商名称「{客商名称}」金额「{record["本币金额"]:.2f}」，凭证日期「{凭证日期}」距今超过3个月')
                write_data.append({
                    '分组关键词': 客商名称,
                    '凭证日期': format_date(record['凭证日期']),
                    '凭证类型': record['凭证类型'],
                    '凭证编号': record['凭证编号'],
                    '客商名称': 客商名称,
                    '本币金额': record['本币金额'],
                    '文本': record['文本']
                })
            else:
                log_with_company(公司代码, "debug",
                                 f'√ BZ类型凭证「{record["凭证编号"]}」，按客商名称「{客商名称}」金额「{record["本币金额"]:.2f}」，凭证日期「{凭证日期}」距今不超过3个月')
                write_data.append({
                    '分组关键词': 客商名称,
                    '凭证日期': format_date(record['凭证日期']),
                    '凭证类型': record['凭证类型'],
                    '凭证编号': record['凭证编号'],
                    '客商名称': 客商名称,
                    '本币金额': record['本币金额'],
                    '文本': record['文本']
                })

    # # 处理负数金额
    # negative_amounts = grouped[grouped['本币金额'] < 0]
    # log_with_company(公司代码, "info", f"BZ类型负数金额共{len(negative_amounts)}组")
    #
    # for _, row in negative_amounts.iterrows():
    #     小计金额 = row['本币金额']
    #     客商名称 = row['客商名称']
    #
    #     original_records = df_filtered[df_filtered['客商名称'] == 客商名称]
    #
    #
    #     # 遍历所有原始记录
    #     for _, record in original_records.iterrows():
    #         凭证日期 = format_date(record['凭证日期'])
    #         # 转换凭证日期为datetime格式
    #         voucher_date = pd.to_datetime(record['凭证日期'])
    #         days_diff = get_days_diff(current_date, voucher_date)
    #         if days_diff > 90:
    #             log_with_company(公司代码, "error",
    #                              f'× BZ类型凭证「{record["凭证编号"]}」，按客商名称「{客商名称}」小计为负「{小计金额:.2f}」，凭证日期「{凭证日期}」距今超过3个月')
    #
    #             # 写入所有记录，并添加客商名称作为分组关键词
    #             write_data.append({
    #                 '分组关键词': 客商名称,
    #                 '凭证日期': format_date(record['凭证日期']),
    #                 '凭证类型': record['凭证类型'],
    #                 '凭证编号': record['凭证编号'],
    #                 '客商名称': 客商名称,
    #                 '本币金额': record['本币金额'],
    #                 '文本': record['文本']
    #             })
    #         else:
    #             log_with_company(公司代码, "debug",
    #                              f'√ BZ类型凭证「{record["凭证编号"]}」，按客商名称「{客商名称}」小计为负「{小计金额:.2f}」，凭证日期「{凭证日期}」距今均不超过3个月')

    return write_data
